package com.asset.dispoal.file.repayment.domain.service.common;

import com.asset.dispoal.business.bsCase.domain.db.entity.BsCase;
import com.asset.dispoal.business.bsCase.domain.db.entity.BsCaseDisposalFile;
import com.asset.dispoal.business.bsCase.domain.db.entity.BsCaseMediation;
import com.asset.dispoal.business.bsCase.domain.db.mapper.BsCaseMapper;
import com.asset.dispoal.business.bsCase.domain.db.mapper.BsCaseMediationMapper;
import com.asset.dispoal.business.mediation.domain.db.entity.ReduceStagingTmp;
import com.asset.dispoal.business.mediation.domain.db.mapper.ReduceStagingTmpMapper;
import com.asset.dispoal.business.repayment.domain.db.entity.BsCaseRepayment;
import com.asset.dispoal.business.repayment.domain.db.entity.BsCaseRepaymentLogs;
import com.asset.dispoal.business.repayment.domain.db.mapper.CaseRepaymentLogsMapper;
import com.asset.dispoal.business.repayment.domain.db.mapper.CaseRepaymentMapper;
import com.asset.dispoal.file.repayment.domain.service.converter.RepaymetConverter;
import com.asset.dispoal.file.repayment.dto.SaveRepaymentInfoRequest;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import tech.mhuang.pacebox.core.date.DateTimeUtil;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.exception.BusinessException;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.StringUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.protocol.Result;

import java.io.File;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author: yf
 * @date: 2022-09-30 13:46:28
 */
@Repository
public class SaveRepaymentInfoCommand implements BaseCommand<SaveRepaymentInfoRequest, Result> {
    @Autowired
    private CaseRepaymentMapper caseRepaymentMapper;
    @Autowired
    private BsCaseMapper caseMapper;
    @Autowired
    private ReduceStagingTmpMapper reduceStagingTmpMapper;
    @Autowired
    private BsCaseMediationMapper bsCaseMediationMapper;
    @Autowired
    private CaseRepaymentLogsMapper caseRepaymentLogsMapper;

    @Autowired
    private BaseIdeable<String> ideable;
    @Autowired
    private Environment environment;

    @Override
    @SneakyThrows
    @Transactional
    public Result execute(SaveRepaymentInfoRequest request) {
        String repaymentId;

        BsCase bsCase = caseMapper.getCaseById(request.getCaseId());
        //判断操作还款项id是否为空， 为空的话新建一条还款记录
        if (StringUtil.isEmptyNull(request.getId())) {
            repaymentId = ideable.generateId();
            request.setId(repaymentId);
            BsCaseRepayment caseRepayment = RepaymetConverter.INSTANCE.resToDo(request);
            caseRepayment.setRepaymentCaseState(bsCase.getCaseState());
            caseRepayment.setDeleted("0");
            int res = caseRepaymentMapper.insert(caseRepayment);
            if (res <= 0) {
                throw new BusinessException(500, "系统异常！", "");
            }
        } else {
            repaymentId = request.getId();
            //判断案件状态， 如果是和解 或者 调解, 如果都不是默认走还款表
            switch (bsCase.getCaseState()) {
                case "reconciliation":
                    reconciliationHandler(request, bsCase.getCaseState());
                    break;
                case "mediation":
                    mediationHandler(request);
                    break;
                default:
                    defaultHandler(request, bsCase.getCaseState());
                    break;
            }

        }

        List<String> fileIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(request.getRepayFiles())) {
            //插入还款文件
            String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
            String headUrl = environment.getProperty("file.evidence.url");
            String caseRegisterFolder = environment.getProperty("file.repaymentFile.url");
            LocalDateTime currentLocalDate = LocalDateTime.now();
            Path relativePath = Paths.get(caseRegisterFolder,
                    String.valueOf(currentLocalDate.getYear()),
                    String.valueOf(currentLocalDate.getMonthValue()),
                    String.valueOf(currentLocalDate.getDayOfMonth())
            );

            Path checkDirFile = Paths.get(headUrl, relativePath.toString());
            if (Files.notExists(checkDirFile)) {
                Files.createDirectories(checkDirFile);
            }
            for (MultipartFile file : request.getRepayFiles()) {
                String fileId = ideable.generateId();
                fileIds.add(fileId);
                String originalName = file.getOriginalFilename();
                String replaceName = ideable.generateId() + originalName;
                file.transferTo(Paths.get(checkDirFile.toString(), replaceName));
                BsCaseDisposalFile caseDisposalFile = new BsCaseDisposalFile();
                caseDisposalFile.setCaseId(request.getCaseId());
                caseDisposalFile.setId(fileId);
                caseDisposalFile.setCurrentState(bsCase.getCaseState());
                caseDisposalFile.setReplaceName(replaceName);
                caseDisposalFile.setOriginalName(originalName);
                caseDisposalFile.setFilePath(relativePath + File.separator + replaceName);
                caseDisposalFile.setFileType("repaymentFile");
                caseDisposalFile.setCreateUser(userId);
                caseDisposalFile.setOperateUser(userId);
                caseDisposalFile.setCreateTime(DateTimeUtil.localDateTimeToDate(currentLocalDate));
                caseDisposalFile.setOperateTime(DateTimeUtil.localDateTimeToDate(currentLocalDate));
                caseDisposalFile.setUploadWay("0");
                caseMapper.insertDisposeFile(caseDisposalFile);
            }
        }

        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        BsCaseRepaymentLogs caseRepaymentLogs = BsCaseRepaymentLogs.builder()
                .id(ideable.generateId())
                .caseId(bsCase.getId())
                .repaymentId(repaymentId)
                .currentRepaymentPrincipal(new BigDecimal(request.getCurrentRepaymentPrincipal()))
                .currentRepaymentInterest(new BigDecimal(request.getCurrentRepaymentInterest()))
                .currentRepaymentPenalty(new BigDecimal(request.getCurrentRepaymentPenalty()))
                .currentRepaymentLitigationAmount(nullValueHandler(request.getCurrentRepaymentLitigationAmount()))
                .currentRepaymentPreservationAmount(nullValueHandler(request.getCurrentRepaymentPreservationAmount()))
                .repaymentTime(request.getRepaymentTime())
                .repaymentFileIds(String.join(",", fileIds))
                .repaymentCaseState(bsCase.getCaseState())
                .repaymentType(request.getRepaymentType())
                .createUserId(userId)
                .createTime(new Date())
                .approvalState("1")
                .build();
        //插入还款记录表
        int insertRes = caseRepaymentLogsMapper.insert(caseRepaymentLogs);
        if (insertRes <= 0) {
            throw new BusinessException(500, "保存信息失败！", "");
        }

        return Result.ok();
    }

    /**
     * 调解处理逻辑
     *
     * @param request
     */
    private void mediationHandler(SaveRepaymentInfoRequest request) {
        BsCaseMediation bsCaseMediation = bsCaseMediationMapper.queryById(request.getId());
        //计算已还金额
        BigDecimal repaymentPrincipal = nullValueToZero(bsCaseMediation.getRepaymentPrincipal()).add(new BigDecimal(request.getCurrentRepaymentPrincipal()));
        BigDecimal repaymentInterest = nullValueToZero(bsCaseMediation.getRepaymentInterest()).add(new BigDecimal(request.getCurrentRepaymentInterest()));
        BigDecimal repaymentPenalty = nullValueToZero(bsCaseMediation.getRepaymentPenalty()).add(new BigDecimal(request.getCurrentRepaymentPenalty()));
        bsCaseMediation.setRepaymentPrincipal(repaymentPrincipal);
        bsCaseMediation.setRepaymentInterest(repaymentInterest);
        bsCaseMediation.setRepaymentPenalty(repaymentPenalty);
        bsCaseMediation.setRepaymentTime(request.getRepaymentTime());
        int update = bsCaseMediationMapper.update(bsCaseMediation);
        if (update <= 0) {
            throw new BusinessException(500, "系统异常！", "");
        }
    }

    /**
     * 和解还款逻辑
     *
     * @param request
     */
    private void reconciliationHandler(SaveRepaymentInfoRequest request, String caseState) {
        //查询分期数的id
        ReduceStagingTmp reduceStagingTmp = reduceStagingTmpMapper.queryById(request.getId());
        //计算已还金额
        BigDecimal repaymentPrincipal = nullValueToZero(reduceStagingTmp.getRepaymentPrincipalAmount()).add(new BigDecimal(request.getCurrentRepaymentPrincipal()));
        BigDecimal repaymentInterest = nullValueToZero(reduceStagingTmp.getRepaymentInterestAmount()).add(new BigDecimal(request.getCurrentRepaymentInterest()));
        BigDecimal repaymentPenalty = nullValueToZero(reduceStagingTmp.getRepaymentLitigationFines()).add(new BigDecimal(request.getCurrentRepaymentPenalty()));
        reduceStagingTmp.setRepaymentPrincipalAmount(repaymentPrincipal);
        reduceStagingTmp.setRepaymentInterestAmount(repaymentInterest);
        reduceStagingTmp.setRepaymentLitigationFines(repaymentPenalty);
        int update = reduceStagingTmpMapper.update(reduceStagingTmp);
        if (update <= 0) {
            throw new BusinessException(500, "系统异常！", "");
        }
    }


    /**
     * 默认处理逻辑
     *
     * @param request
     */
    private void defaultHandler(SaveRepaymentInfoRequest request, String caseState) {
        BsCaseRepayment caseRepayment = caseRepaymentMapper.queryById(request.getId());
        //计算已还金额
        BigDecimal repaymentPrincipal = nullValueToZero(caseRepayment.getRepaymentPrincipal()).add(new BigDecimal(request.getCurrentRepaymentPrincipal()));
        BigDecimal repaymentInterest = nullValueToZero(caseRepayment.getRepaymentInterest()).add(new BigDecimal(request.getCurrentRepaymentInterest()));
        BigDecimal repaymentPenalty = nullValueToZero(caseRepayment.getRepaymentPenalty()).add(new BigDecimal(request.getCurrentRepaymentPenalty()));
        caseRepayment.setRepaymentPrincipal(repaymentPrincipal);
        caseRepayment.setRepaymentInterest(repaymentInterest);
        caseRepayment.setRepaymentPenalty(repaymentPenalty);
        caseRepayment.setIsPay(request.getIsPay());


        int update = caseRepaymentMapper.update(caseRepayment);
        if (update <= 0) {
            throw new BusinessException(500, "系统异常！", "");
        }
    }


    /**
     * 空值处理为0值
     */
    private BigDecimal nullValueToZero(BigDecimal bigDecimal) {
        return bigDecimal == null ? BigDecimal.ZERO : bigDecimal;
    }

    /**
     * 空值处理
     *
     * @param bigDecimal
     * @return
     */
    private BigDecimal nullValueHandler(String bigDecimal) {
        if (StringUtil.isEmptyNull(bigDecimal)) {
            return null;
        }
        return new BigDecimal(bigDecimal);
    }
}